<?php
/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2020/08/24
 * Time: 18:13
 * @link http://www.lmterp.cn
 */

namespace app\common\service\import;

use app\common\library\Tools;
use app\common\model\Account;
use app\common\model\AccountPlatform;
use app\common\model\SysCountries;
use app\common\model\Orders;
use app\common\model\OrdersDetail;
use app\common\model\ProductPlatformSku;
use app\common\model\ProductStore;
use app\common\service\orders\OrderService;

/**
 * 订单导入
 * Class Order
 * @package app\common\service\import
 */
class Order extends BaseImport
{
    /**
     * 交换键值后读入头信息
     * @var array
     */
    protected $horder = [];

    /**
     * 原读入头信息
     * @var array
     */
    protected $eorder = [];

    /**
     * 是否为首行
     * @var bool
     */
    protected $isFirst = true;

    /**
     * 不导入字段
     * @var array
     */
    protected $excludeField = [
        'orders.create_by', 'detail.create_time'
    ];

    public function init()
    {
        $this->eorder = (new \app\common\service\export\Order())->getHeader();
        $this->horder = array_flip($this->eorder);
    }

    /**
     * @inheritDoc
     */
    protected function write()
    {
        foreach($this->buildOrderData() as $orders)
        {
           OrderService::getInstance()->addOrder($orders);
        }
    }

    /**
     * 组装订单数据
     * @return array
     * @date 2020/08/30
     * @author longli
     */
    protected function buildOrderData()
    {
        $tempOrder = [];
        $currentNo = null;
        foreach($this->getData() as $row)
        {
            foreach($this->excludeField as $k)
            {
               unset($row[$k]);
            }
            if(!isset($tempOrder[$row['orders.order_no']]) && !empty($row['orders.order_no']))
            {
                $currentNo = $row['orders.order_no'];
            }
            if(empty($currentNo)) continue;
            $tempOrder[$currentNo][] = $row;
        }
        $ret = [];
        foreach($tempOrder as $orders)
        {
            krsort($orders);
            $info = [];
            foreach($orders as $order)
            {
                $this->transform($order);
                $t = [];
                foreach($order as $k => $v)
                {
                    if(Tools::startWith($k, 'detail.'))
                        $t[substr($k, 7)] = $v;
                }
                $info[] = $t;
            }
            $iorder = ['order_detail' => $info];
            foreach($order as $k => $v)
            {
                if(Tools::startWith($k, 'orders.'))
                    $iorder[substr($k, 7)] = $v;
            }
            $ret[] = $iorder;
        }
        return $ret;
    }

    /**
     * 数据转换为可写入数据库的格式
     * @param array $row
     * @date 2020/08/30
     * @author longli
     */
    protected function transform(& $row = [])
    {
        if(!empty($row['orders.account_id']))
        {
            $row['orders.account_id'] = Account::get(['username' => $row['orders.account_id']])->account_id;
        }
        if(!empty($row['orders.order_status']))
        {
            $row['orders.order_status'] = array_flip(Orders::$ORDER_STATUS)[$row['orders.order_status']];
        }
        if(!empty($row['orders.send_status']))
        {
            $row['orders.send_status'] = array_flip(Orders::$SEND_STATUS)[$row['orders.send_status']];
        }
        if(!empty($row['orders.is_print']))
        {
            $row['orders.is_print'] = array_flip(Orders::$PRINT_STATUS)[$row['orders.is_print']];
        }
        if(!empty($row['orders.is_flag_sent']))
        {
            $row['orders.is_flag_sent'] = array_flip(Orders::$FLAG_STATUS)[$row['orders.is_flag_sent']];
        }
        if(!empty($row['detail.is_bundle']))
        {
            $row['detail.is_bundle'] = array_flip(OrdersDetail::$BUNDLE_STATUS)[$row['detail.is_bundle']];
        }
        if(!empty($row['detail.is_cancel']))
        {
            $row['detail.is_cancel'] = array_flip(OrdersDetail::$CANCEL_STATUS)[$row['detail.is_cancel']];
        }
        if(empty($row['orders.buyer_country_code']))
        {
            $row['orders.buyer_country_code'] = SysCountries::field('code_two')->where(['name_en' => $row['orders.buyer_country']])
                    ->whereOr(['name_ch' => $row['orders.buyer_country']])->find()->code_two;
        }
        if(!empty($row['orders.latest_delivery_time']))
        {
            if(is_numeric($row['orders.latest_delivery_time'])) $row['orders.latest_delivery_time'] = date('Y-m-d', strtotime("{$row['orders.latest_delivery_time']}day"));
            if(($time = strtotime($row['orders.latest_delivery_time'])) !== false) $row['orders.latest_delivery_time'] = date('Y-m-d H:i:s', $time);
            else $row['orders.latest_delivery_time'] = null;
        }
        if(!empty($row['orders.order_source_create_time']))
        {
            if(Tools::isDate($row['orders.order_source_create_time'], $time)) $row['orders.order_source_create_time'] = Tools::now($time);
            else $row['orders.order_source_create_time'] = null;
        }
        // 如果时间字段为空字符串，则全部过虑掉
        foreach(['detail.create_time', 'orders.order_source_create_time', 'orders.sent_time', 'orders.order_pay_time',
                'orders.track_num_time', 'orders.shipping_time', 'orders.latest_delivery_time'] as $v)
        {
            if(empty($row[$v])) unset($row[$v]);
        }
    }

    /**
     * @inheritDoc
     */
    protected function validate(&$row = [], $key = 0)
    {
        $row = Tools::replaceArrayKey($this->horder, $row);
        $this->isFirst = $key == 0 || !empty($row["orders.account_id"]);
        list($order, $detail) = $this->parseOrder($row);
        $vo = $this->validateOrder($order);
        $vd = $this->validateDetail($detail);
        if($vo === true && $vd === true) return true;
        $msg = "";
        if($vo !== true) $msg .= "$vo, ";
        if($vd !== true) $msg .= $vd;
        return $msg;
    }

    /**
     * 解析订单分开验证
     * @param array $order 一条订单数据
     * @return array
     * @date 2020/08/29
     * @author longli
     */
    protected function parseOrder($order = [])
    {
        $t = $d = [];
        foreach($order as $key => $item)
        {
            if(Tools::startWith($key, "detail."))
            {
                $d[$key] = $item;
            }
            else
            {
                $t[$key] = $item;
            }
        }
        return [$t, $d];
    }

    /**
     * 验证订单
     * @param array $order 订单数据
     * @return bool|string
     * @date 2020/08/29
     * @author longli
     */
    protected function validateOrder($order = [])
    {
        $error = [];
        if($this->isFirst)
        {
            // 必填字段
            $requireField = [
                'orders.order_no', 'orders.account_id', 'orders.order_price', 'orders.currency',
                'orders.buyer_post_code', 'orders.buyer_city', 'orders.buyer_address_1',
            ];
            if(($req = $this->requireField($order, $requireField, $this->eorder)) !== true) $error = array_merge($error, $req);
            // 必填一个字段
            $requireOr = ['orders.consignee', 'orders.buyer_first_name'];
            if(($reqOr = $this->requireOr($order, $requireOr, $this->eorder)) !== true) $error[] = join(" 或 ", $reqOr) . "必填一个";

            $reqOrCountry = ['orders.buyer_country_code', 'orders.buyer_country'];
            if(($reqOr = $this->requireOr($order, $reqOrCountry, $this->eorder)) !== true) $error[] = join(" 或 ", $reqOr) . "必填一个";

            $reqOrPhone = ['orders.buyer_phone', 'orders.buyer_mobile'];
            if(($reqOr = $this->requireOr($order, $reqOrPhone, $this->eorder)) !== true) $error[] = join(" 或 ", $reqOr) . "必填一个";
        }
        if(empty($error))
        {
            // 验证格式
            if(!empty($order['orders.account_id']) &&!Account::where(['username' => $order['orders.account_id']])->count())
                $error[] = $this->eorder["orders.account_id"] . "【{$order['orders.account_id']}】不存在";
            if(!empty($order['orders.platform_name']) && !AccountPlatform::where(["name" => $order['orders.platform_name']])->count())
                $error[] = $this->eorder["orders.platform_name"] . "【{$order['orders.platform_name']}】不存在";
            if(!empty($order['orders.order_status']) && !in_array($order['orders.order_status'], Orders::$ORDER_STATUS))
                $error[] = $this->eorder["orders.order_status"] . "【{$order['orders.order_status']}】格式有误";
            if(!empty($order['orders.currency']) && !SysCountries::where(['currency_code' => $order['orders.currency']])->count())
                $error[] = $this->eorder["orders.currency"] . "【{$order['orders.currency']}】不存在";
            if(!empty($order['orders.buyer_country_code']) && !SysCountries::where(["code_two" => $order['orders.buyer_country_code']])
                    ->whereOr(["code_three" => $order['orders.buyer_country_code']])->count())
                $error[] = $this->eorder["orders.buyer_country_code"] . "【{$order['orders.buyer_country_code']}】不存在";
            if(!empty($order['orders.buyer_country']) && !SysCountries::where(["name_ch" => $order['orders.buyer_country']])
                    ->whereOr(["name_en" => $order['orders.buyer_country']])->count())
                $error[] = $this->eorder["orders.buyer_country"] . "【{$order['orders.buyer_country']}】不存在";
            if(!empty($order['orders.is_flag_sent']) && !in_array($order['orders.is_flag_sent'], Orders::$FLAG_STATUS))
                $error[] = $this->eorder["orders.is_flag_sent"] . "【{$order['orders.is_flag_sent']}】格式有误";
            if(!empty($order['orders.is_print']) && !in_array($order['orders.is_print'], Orders::$PRINT_STATUS))
                $error[] = $this->eorder["orders.is_print"] . "【{$order['orders.is_print']}】格式有误";
            if(!empty($order['orders.send_status']) && !in_array($order['orders.send_status'], Orders::$SEND_STATUS))
                $error[] = $this->eorder["orders.send_status"] . "【{$order['orders.send_status']}】格式有误";
            // 验证数字
            $validateNum = ['orders.order_id', 'orders.profit', 'orders.weight', 'orders.weight', 'orders.refund', 'orders.target_refund',
                'orders.logistics_price', 'orders.shipping_price', 'orders.discount_amount', 'orders.commission_cost',
                'orders.surcharge_price', 'orders.order_price', 'orders.total_price'
            ];
            if(($valiNum = $this->validateNumber($order, $validateNum, $this->eorder)) !== true) $error = array_merge($error, $valiNum);
            // 验证时间
            $validateTime = ['orders.order_pay_time', 'orders.order_source_create_time'];
            if(($valiTime = $this->validateDate($order, $validateTime, $this->eorder)) !== true) $error = array_merge($error, $valiTime);
        }
        return !empty($error) ? join(", ", $error) : true;
    }

    /**
     * 验证订单详情
     * @param array $detail 订单详情
     * @return bool|string
     * @date 2020/08/29
     * @author longli
     */
    protected function validateDetail($detail = [])
    {
        $error = [];
        // 必填字段
        $requireField = ['detail.sku', 'detail.qty', 'detail.price'];
        if(($req = $this->requireField($detail, $requireField, $this->eorder)) !== true) $error = array_merge($error, $req);
        if(empty($error))
        {
            // 验证格式
            if(!empty($detail['detail.sku']) && !ProductStore::where(['sku' => $detail['detail.sku']])->count())
                $error[] = $this->eorder["detail.sku"] . "【{$detail['detail.sku']}】不存在";
            if(!empty($detail['detail.platform_sku']) && !ProductPlatformSku::where(['platform_sku' => $detail['detail.platform_sku']])->count())
                $error[] = $this->eorder["detail.platform_sku"] . "【{$detail['detail.platform_sku']}】不存在";
            if(!empty($detail['detail.is_cancel']) && !in_array($detail['detail.is_cancel'], OrdersDetail::$CANCEL_STATUS))
                $error[] = $this->eorder["detail.is_cancel"] . "【{$detail['detail.is_cancel']}】格式有误";
            if(!empty($detail['detail.is_bundle']) && !in_array($detail['detail.is_bundle'], OrdersDetail::$BUNDLE_STATUS))
                $error[] = $this->eorder["detail.is_bundle"] . "【{$detail['detail.is_bundle']}】格式有误";

            // 验证数字
            $validateNum = ['detail.detail_id', 'detail.qty', 'detail.return_qty', 'detail.price', 'detail.declare_price'];
            if(($valiNum = $this->validateNumber($detail, $validateNum, $this->eorder)) !== true) $error = array_merge($error, $valiNum);
        }
        return !empty($error) ? join(", ", $error) : true;
    }
}